package com.koron.common.core.business.todoApproval.util;


import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.koron.common.core.business.todoApproval.bean.MessageCommonEntry;
import com.koron.common.core.business.todoApproval.bean.ZsjConfigInfo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;

@Component
@RefreshScope
@Slf4j
@Data
public class ZsjSendTodoUtil {

    private static final Integer SUCCESS_CODE = 200;
    private static final String authCodeKey = "authCode";
    private static TimedCache<String, String> authCodeCaChe = CacheUtil.newTimedCache(24 * 60 * 60 * 1000);

    static {
        // 定期清理过期缓存，时间间隔为1小时
        authCodeCaChe.schedulePrune(24 * 60 * 60 * 1000);
    }

    @Autowired
    private ZsjConfigInfo zsjConfigInfo;

    @Value("${todo.opened:false}")
    private boolean opened;


    public void refreshAuthCode() {
        String loginUrl = zsjConfigInfo.getLoginUrl();
        String username = zsjConfigInfo.getUsername();
        String password = zsjConfigInfo.getPassword();
        String loginNameMd5 = DigestUtils.md5Hex(username).toLowerCase();
        String passwordMd5 = DigestUtils.md5Hex(password).toLowerCase();
        String responseStr = HttpUtil.createGet(loginUrl)
                .form("loginNameMd5", loginNameMd5)
                .form("passwordMd5", passwordMd5)
                .execute()
                .body();
        log.info("待办获取授权码响应={}", responseStr);
        String authCode = (String) JSONUtil.getByPath(JSONUtil.parse(responseStr), "data");
        authCodeCaChe.put("authCode", authCode);
    }


    public String api(String url, Map<String, Object> params) throws InterruptedException {
        int retryTime = 0;
        int maxRetry = 3; // 最大重试次数
        int retryInterval = 500; // 重试间隔 ms

        log.info("请求url={},参数params={}", url, params);

        if (StringUtils.isEmpty(url)){
            log.info("参数url不能为空！");
            return null;
        }

        while (retryTime < maxRetry) {
            try {
                String authCode = authCodeCaChe.get(authCodeKey);
                if (Objects.isNull(authCode)) {
                    refreshAuthCode();
                    authCode = authCodeCaChe.get(authCodeKey);
                }

                log.info("请求url={},授权码authCode={}", url, authCode);
                String response = HttpUtil.createGet(url)
                        .header("wsToken", authCode)
                        .timeout(5000) //设置超时时间
                        .form(params)
                        .execute()
                        .body();

                Integer responseCode = (Integer) JSONUtil.getByPath(JSONUtil.parse(response), "code");
                if (!responseCode.equals(SUCCESS_CODE)) {
                    refreshAuthCode();
                    authCode = authCodeCaChe.get(authCodeKey);
                    response = HttpUtil.createGet(url)
                            .header("wsToken", authCode)
                            .timeout(5000) //设置超时时间
                            .form(params)
                            .execute()
                            .body();
                }
                log.info("url={},响应={}", url, response);
                return response; // 请求成功，退出重试循环
            } catch (HttpException e) {
                log.warn("调用接口失败，进行第{}次重试", retryTime);
                Thread.sleep(retryInterval);
                retryTime++;
                if (retryTime > maxRetry) {
                    throw new RuntimeException("超过最大重试次数！");
                }
            }
        }
        return null;
    }


    public void api(String url, List<MessageCommonEntry> messageCommonEntryList) throws InterruptedException {
        if (!opened){
            log.info("请打开发送待办开关！");
            return;
        }

        int retryTime = 0;
        int maxRetry = 3; // 最大重试次数
        int retryInterval = 500; // 重试间隔 ms

        log.info("请求url={},参数params={}", url, messageCommonEntryList);

        if (StringUtils.isEmpty(url)){
            log.info("参数url不能为空！");
            return;
        }

        if (CollectionUtils.isEmpty(messageCommonEntryList)) {
            log.info("参数messageCommonEntryList不能为空！");
            return;
        }


        String commonEntry = JSONUtil.toJsonStr(messageCommonEntryList);
        log.info("请求url={},参数messageCommonEntryList={}", url, commonEntry);
        String authCode = authCodeCaChe.get(authCodeKey);

        if (Objects.isNull(authCode)) {
            refreshAuthCode();
            authCode = authCodeCaChe.get(authCodeKey);
        }
        log.info("请求url={},授权码authCode={}", url, authCode);
        while (retryTime < maxRetry) {
            try {

                String response = HttpUtil.createPost(url)
                        .header("wsToken", authCode)
                        .timeout(5000) //设置超时时间
                        .body(commonEntry)
                        .execute()
                        .body();

                Integer responseCode = (Integer) JSONUtil.getByPath(JSONUtil.parse(response), "code");
                if (!responseCode.equals(SUCCESS_CODE)) {
                    refreshAuthCode();
                    authCode = authCodeCaChe.get(authCodeKey);
                    response = HttpUtil.createPost(url)
                            .header("wsToken", authCode)
                            .timeout(5000) // 设置超时时间
                            .body(commonEntry)
                            .execute()
                            .body();
                }
                log.info("url={},响应={}", url, response);
                return; // 请求成功，退出重试循环
            } catch (HttpException e) {
                log.warn("调用接口失败，进行第{}次重试", retryTime);
                Thread.sleep(retryInterval);
                retryTime++;
                if (retryTime > maxRetry) {
                    throw new RuntimeException("超过最大重试次数！");
                }
            }
        }
    }

    /**
     * 发起待办信息
     *
     * @param messageCommonEntryList
     */
    public void addStart(List<MessageCommonEntry> messageCommonEntryList) throws InterruptedException {
        String addStartUrl = zsjConfigInfo.getAddStartUrl();
        api(addStartUrl, messageCommonEntryList);
    }


    /**
     * 新增待办消息
     *
     * @param messageCommonEntryList
     * @throws InterruptedException
     */
    public void addTodo(List<MessageCommonEntry> messageCommonEntryList) throws InterruptedException {
        String addTodoUrl = zsjConfigInfo.getAddTodoUrl();
        api(addTodoUrl, messageCommonEntryList);
    }

    /**
     * 待办信息办理之后转参与
     *
     * @param messageCommonEntryList
     * @throws InterruptedException
     */
    public void updateTodoDone(List<MessageCommonEntry> messageCommonEntryList) throws InterruptedException {
        String updateTodoDoneUrl = zsjConfigInfo.getUpdateTodoDoneUrl();
        api(updateTodoDoneUrl, messageCommonEntryList);
    }

    public String messageListPage(Map<String, Object> params) throws InterruptedException {
        String messageListPageUrl = zsjConfigInfo.getMessageListPageUrl();
        return api(messageListPageUrl, params);
    }



}
